#pragma once
#include "IObserver.h"
#include <iostream>
#include "Subject.h"

class Observer : public IObserver {
public:
	Observer(ConcreteSubject& subject) : subject_(subject) {
		this->subject_.Attach(this);
		std::cout << "Hi, I'm the Observer \"" << ++Observer::static_number_ << "\".\n";
		this->number_ = Observer::static_number_;
	}
	virtual ~Observer() {
		std::cout << "Goodbye, I was the Observer \"" << this->number_ << "\".\n";
	}
	virtual void Update(ISubject* Subject, BaseMessageInfo* BaseData) override
	{
		
		if (typeid(*Subject) == typeid(Observer))
		{
			if (BaseData && typeid(*Subject) == typeid(Observer))
			{
				ConcreteSubjectMessageInfo* SubjectMessageInfo = static_cast<ConcreteSubjectMessageInfo*>(BaseData);
				message_from_subject_ = SubjectMessageInfo->message_;
				PrintInfo();
			}
			else
			{
				ConcreteSubject* TempConcreteSubject = dynamic_cast<ConcreteSubject*>(Subject);
				message_from_subject_ = TempConcreteSubject->GetMessage();
				PrintInfo();
			}
		}
	}
	void RemoveMeFromTheList() {
		subject_.Detach(this);
		std::cout << "Observer \"" << number_ << "\" removed from the list.\n";
	}
	void PrintInfo() {
		std::cout << "Observer \"" << this->number_ << "\": a new message is available --> " << this->message_from_subject_ << "\n";
	}

private:
	std::string message_from_subject_;
	ConcreteSubject& subject_;
	static int static_number_;
	int number_;
};